
package edu.chalmers.AV_2DPlatformerFramework.View;

import edu.chalmers.AV_2DPlatformerFramework.Model.GameObject;
import edu.chalmers.AV_2DPlatformerFramework.Utility.Vector2D;

/**
 * Basically a Point, but with some added functionality specific
 * to camera management.
 * @version 0.2
 * @author Richard Sundqvist
 * @revised Andrea Buchholz, Richard Sundqvist: 080514
 */

public class Camera {
    /**
     * The (x,y) coordinates of this Camera.
     */
    private int x, y;
    /**
     * The GameObject this Camera will chase by default.
     */
    private GameObject chaseObject;
    /**
     * The distance the Camera will keep from a given chase object.
     */
    private int dX, dY;
    
    /**
     * Creates a new Camera.
     */
    public Camera(){
        this(null, 400, 200);
    }
    /**
     * Creates a new Camera.
     * @param chaseObject The object to chase by default.
     * @param x_dist The x-distance to keep from a given chaseObject.
     * @param y_dist The y-distance to keep from a given chaseObject.
     */
    public Camera (GameObject chaseObject, int x_dist, int y_dist){
        this.chaseObject = chaseObject;
        this.dX = x_dist;
        this.dY = y_dist;
    }
    

    
    /**
     * Sets the position of the camera.
     * @param x The new x-coordinate of the camera.
     * @param y The new y-coordinate of the camera.
     */
    public void place(int x, int y){
        this.x = x;
        this.y = y;
    }
    
    /**
     * Move the camera a given distance along the axes.
     * @param deltaX The x-axis distance to move.
     * @param deltaY The y-axis distance to move.
     */
    public void move(int deltaX, int deltaY){
        this.x += deltaX;
        this.y += deltaY;
    }
    
    /**
     * Moves the camera a given distance from its current point in the direction
     * given in counter-clockwise degrees from the positive x-axis.
     * @param radius The distance to move from the given point.
     * @param degrees The angle in which to move
     */
    public void move(double radius, double degrees){
        double radians = degrees*Math.PI/180;
        x = (int)(x + radius*Math.cos(radians) + 0.5);
        y = (int)(y - radius*Math.sin(radians) + 0.5);
    }
    
    /**
     * Returns the position of a given GameObject, relative to this Camera.
     * Will NOT change the position of the Game object.
     * @param go The GameObect whose position is to be calculated in relation to this Camera.
     * @return Position relative to this Camera.
     */
    
    public Vector2D getRelativeCoordinatesFor(GameObject go){
//        System.out.println("GO pos: " + go.getPosition());
//        System.out.println("CAM pos: [" + x + ", " + y + "]");
        return new Vector2D(go.getPosition().x - this.x, go.getPosition().y - this.y);
    }
    
    /**
     * Place this Camera so that the upper left corner of the screen is a given distance from the given GameObject's anchor point.
     * @param go The GameObject to which this Camera will be adjusted.
     * @param dX GameObject distance from the left edge.
     * @param dY GameObject distance from the top edge.
     */
    public void placeRelativeToObject(GameObject go, int dX, int dY){
//        System.out.println(go.getPosition());
        place(  
                (int)(go.getPosition().x + 0.5) - dX,
                (int)(go.getPosition().y + 0.5) - dY
             );
    }
    public void placeRelativeToObject(GameObject go){
        placeRelativeToObject(go, dX, dY);
    }
    public void placeRelativeToObject(){
        placeRelativeToObject(chaseObject, dX, dY);
    }
                
    /**
     * Returns the x-coordinate of the camera
     * @return
     */
    public int getX(){
        return this.x;
    }
    
    /**
     * Returns the y-coordinate of the camera
     * @return
     */
    public int getY(){
        return this.y;
    }
    /**
     * Set the chase distance for any object.
     * @param x_dist The x-axis distance.
     * @param y_dist The y-axis distance.
     */
    public void setChaseDistance(int x_dist, int y_dist){
        this.dX = x_dist;
        this.dY = y_dist;        
    }
    /**
     * Returns the x-axis distance this Camera will use when chasing an object.
     * @return The x-axis distance.
     */
    public int getdX(){
        return this.dX;
    }
     /**
     * Returns the y-axis distance this Camera will use when chasing an object.
     * @return The y-axis distance.
     */
    public int getdY(){
        return this.dY;
    }
}